package com.jk.vehicle.mini.util;


import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.util.encoders.Base64;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;

import javax.crypto.*;
import javax.crypto.spec.DESKeySpec;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;

/**
 * DES加密介绍 DES是一种对称加密算法，所谓对称加密算法即：加密和解密使用相同密钥的算法。DES加密算法出自IBM的研究，
 * 后来被美国政府正式采用，之后开始广泛流传，但是近些年使用越来越少，因为DES使用56位密钥，以现代计算能力，
 * 24小时内即可被破解。虽然如此，在某些简单应用中，我们还是可以使用DES加密算法，本文简单讲解DES的JAVA实现 。
 * 注意：DES加密和解密过程中，密钥长度都必须是8的倍数
 * @author cjc
 * @date 2018/11/19
 */
@Slf4j
public class DESUtil {
	/**
	 * 配置文件位置
	 */
	private static final String PATH = "application.properties";

	/**
	 * 加密密钥
	 */
	private static String password;

	static {
		try {
			Resource resource = new ClassPathResource(PATH);
			password = PropertiesLoaderUtils.loadProperties(resource).getProperty("des.password");
		} catch (IOException e) {
			log.error(e.getMessage());
		}
	}

	/**
	 * des
	 */
	private static final String DES = "DES";

	/**
	 * 转换格式
	 */
	private static final String DES_INSTANCE = "DES";

//	/**
//	 * 测试方法
//	 * @param args 参数
//	 */
//	public static void main(String[] args) {
//
//		// 待加密内容
//		String str = "Jian360425喜爱";
//		// 密码，长度要是8的倍数
//		log.info("密码长度：" + password.length());
//
//		String reStr = DESUtil.encrypt(str);
//		log.info("加密后：" + reStr);
//
//		// 直接将如上内容解密
//		try {
//			reStr = DESUtil.decrypt(reStr);
//			log.info("解密后：" + reStr);
//		} catch (Exception e) {
//			log.info(e.getMessage());
//		}
//	}

	/**
	 * des加密
	 * @param str 待加密字符串
	 * @return 加密结果
	 */
	public static String encrypt(String str) {
		try {
			byte[] datasource = str.getBytes();
			SecureRandom random = new SecureRandom();
			DESKeySpec desKey = new DESKeySpec(password.getBytes());
			// 创建一个密匙工厂，然后用它把DESKeySpec转换成
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
			SecretKey securekey = keyFactory.generateSecret(desKey);
			// Cipher对象实际完成加密操作
			Cipher cipher = Cipher.getInstance(DES);
			// 用密匙初始化Cipher对象
			cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
			// 现在，获取数据并加密
			// 正式执行加密操作
			return new String(Base64.encode(cipher.doFinal(datasource)));
		} catch (Exception e) {
			log.error(e.getMessage());
		}
		return null;
	}

	/**
	 * 解密
	 * @param str 待解密字符串
	 * @return 解密结果
	 */
	public static String decrypt(String str)
			throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException,
			BadPaddingException, IllegalBlockSizeException {
		byte[] src = Base64.decode(str.getBytes());

		// DES算法要求有一个可信任的随机数源
		SecureRandom random = new SecureRandom();
		// 创建一个DESKeySpec对象
		DESKeySpec desKey = new DESKeySpec(password.getBytes());
		// 创建一个密匙工厂
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
		// 将DESKeySpec对象转换成SecretKey对象
		SecretKey securekey = keyFactory.generateSecret(desKey);
		// Cipher对象实际完成解密操作
		Cipher cipher = Cipher.getInstance(DES_INSTANCE);
		// 用密匙初始化Cipher对象
		cipher.init(Cipher.DECRYPT_MODE, securekey, random);
		// 真正开始解密操作
		return new String(cipher.doFinal(src));
	}
}